﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using System.Web;
using Kugar.Core.BaseStruct;
using Kugar.Core.ExtMethod;
using Kugar.Core.Web;
using Kugar.UI.Web.AdminLTE.Authentications;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Http.Extensions;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace Kugar.UI.Web.AdminLTE.Controllers
{
    [ApiExplorerSettings(IgnoreApi = true)]
    public abstract class WebUIBaseController : Controller
    {
        private List<VM_MVCMsgBoxItem> _msgList = null;
        private Lazy<Dictionary<string,CommandHandler>> _dic=new Lazy<Dictionary<string, CommandHandler>>(createHandlers); 

        public virtual IActionResult AjaxCommandHandler()
        {
            var cmdName = Request.GetString("MethodName");

            var handler = _dic.Value.TryGetValue(cmdName);

            if (handler!=null)
            {
                var ret=handler(cmdName);

                return this.NewtonJson(ret);
            }
            else
            {
                return StatusCode(404);
            }
        }

        protected void RegisterCommandHander(string cmdName, CommandHandler handler)
        {
            _dic.Value.Add(cmdName,handler);
        }

        protected WebUIBaseController()
        {
            _msgList = new List<VM_MVCMsgBoxItem>();
        }

        /// <summary>
        /// 跳转到登出页面
        /// </summary>
        protected async Task<IActionResult> GotoLogout(string backUrl)
        {
            //var authenticationType = RouteData.Values.TryGetValue("authenticationType", "default").ToStringEx();
            //var backurl = Request.GetString("backurl");

            if (string.IsNullOrWhiteSpace(backUrl))
            {
                backUrl = Request.GetDisplayUrl();
            }

            var authenticationType = AuthenticationType;// RouteData.Values.TryGetValue("authenticationType", "default").ToStringEx();

            try
            {
                await HttpContext.SignOutAsync(authenticationType);
            }
            catch (Exception e)
            {
            }

            return View("~/Views/ReLogin.cshtml", backUrl);

            return Redirect($"/AdminCore/AdminLogin/Logout/{authenticationType}?backurl={HttpUtility.UrlEncode(backUrl)}");
        }

        /// <summary>
        /// 跳转到登录页
        /// </summary>
        /// <param name="backUrl"></param>
        /// <returns></returns>
        protected async Task<IActionResult> GotoLogin(string backUrl)
        {
            return await GotoLogout(backUrl);
        }

        protected void MsgBox(string message)
        {
            MsgBoxAndScript(msg:message);
        }

        /// <summary>
        /// 弹出信息,并且跳转到上一个页面,如果defaultUrl为空,则调用history.go(-1)
        /// </summary>
        /// <param name="message"></param>
        /// <param name="defaultUrl"></param>
        protected void MsgAndGotoReferer(string message,string defaultUrl="")
        {
            if (Request.Headers.TryGetValue("Referer",out var referer) && referer.HasData() && !string.IsNullOrWhiteSpace(referer.FirstOrDefault()))
            {
                MsgBoxAndGoto(message, referer.FirstOrDefault());
            }
            else if (!string.IsNullOrWhiteSpace(defaultUrl))
            {
                MsgBoxAndGoto(message, defaultUrl);
            }
            else
            {
                MsgBoxAndScript(message, "history.go(-1)");
            }
        }

        protected void MsgBoxAndRefresh(string msg)
        {
            MsgBoxAndGoto(msg,this.Request.GetDisplayUrl());
        }

        /// <summary>
        /// 弹出提示框,点击确认后,跳转指定连接,如果当前页为弹出窗口,则当前窗口跳转到指定url
        /// </summary>
        /// <param name="msg"></param>
        /// <param name="url"></param>
        protected void MsgBoxAndGoto(string msg, string url)
        {
            MsgBoxAndScript(msg, $"WebUIJS.GoTo('{url}',this);");
        }

        protected void MsgBoxAndScript(string msg, string script="")
        {
            if (string.IsNullOrWhiteSpace(msg) && string.IsNullOrWhiteSpace(script))
            {
                return;
            }

            List<VM_MVCMsgBoxItem> msgList = null;

            if (ViewBag.MsgData_Temp ==null)
            {
                ViewBag.MsgData_Temp =_msgList;
            }

            msgList = _msgList;

            msgList.Add(new VM_MVCMsgBoxItem(msg, script));
        }

        /// <summary>
        /// 弹出提示框,点击确定后自动关闭
        /// </summary>
        /// <param name="msg"></param>
        /// <param name="isRefreshPage">关闭时,刷新 页面,如果弹出的上级页面为modal,则刷新上级页面,否则刷新整个页面</param>
        /// <param name="isRefreshWholePage">关闭时,直接刷新整个页面</param>
        protected void MsgBoxAndCloseModal(string msg,bool isRefreshPage=false,bool isRefreshWholePage=false)
        {
            var layerIndex = Request.GetString("layerindex");

            string script;

            if (string.IsNullOrWhiteSpace(layerIndex))
            {
                script = "WebUIJS.CloseModal();";
            }
            else
            {
                script = $"WebUIJS.CloseModal('{layerIndex}');";
            }

            if (isRefreshPage || isRefreshWholePage)
            {
                var fromLayModalID = Request.GetString("fromlayerid");

                script += "WebUIJS.Loading();";

                if (isRefreshWholePage)
                {
                    script += "WebUIJS.Refresh();";
                }
                else
                {
                    if (!string.IsNullOrWhiteSpace(fromLayModalID))
                    {
                        script += $"WebUIJS.Refresh($('#{fromLayModalID} .modalwindow'));";
                    }
                    else
                    {
                        script += "WebUIJS.Refresh();";
                    }

                }
                 
            }

            this.MsgBoxAndScript(msg,script);
        }

        protected void MsgBoxAndCallbackData(string msg, JObject callbackData,bool isCloseModal=false)
        {
            var callbackID = Request.GetString("CallbackID");

            var layerIndex = Request.GetString("layerindex");

            string script;

            if (string.IsNullOrWhiteSpace(layerIndex))
            {
                script = "WebUIJS.CloseModal();";
            }
            else
            {
                script = $"WebUIJS.CloseModal('{layerIndex}');";
            }

            if (!string.IsNullOrWhiteSpace(callbackID))
            {
                MsgBoxAndScript(msg,$"__callFuncByID('{callbackID}',{callbackData.ToString(Formatting.None)});{(isCloseModal? script : "")}");
            }
            else
            {
                MsgBoxAndScript(msg,isCloseModal? script : "");
            }
            
        }

        private List<VM_MVCMsgBoxItem> getMsgList()
        {
            return new List<VM_MVCMsgBoxItem>();
        }

        private static Dictionary<string, CommandHandler> createHandlers()
        {
            return new Dictionary<string, CommandHandler>(StringComparer.CurrentCultureIgnoreCase);
        }

        /// <summary>
        /// 获取经过授权后的当前用户ID,读取的是 HttpContext.User.FindFirst("userid")
        /// </summary>
        /// <returns></returns>
        protected string GetCurrentUserId()
        {
            return HttpContext.User.FindFirst(ClaimTypes.NameIdentifier)?.Value.ToStringEx();
        }


        /// <summary>
        /// 获取当前登录授权使用的SchemeName
        /// </summary>
        /// <returns></returns>
        protected string GetCurrentSchemeName()
        {
            return HttpContext.Items.TryGetValue("SchemeName", "").ToStringEx();
        }

        protected string AuthenticationType
        {
            get
            {
                var authenticationType = RouteData.Values.TryGetValue("authenticationType").ToStringEx();

                if (string.IsNullOrWhiteSpace(authenticationType))
                {
                    return HttpContext.Items["SchemeName"].ToStringEx();
                }

                return authenticationType;
            }
        }

        public override void OnActionExecuting(ActionExecutingContext context)
        {
            var options=(OptionsManager<AdminJWTOption>)context.HttpContext.RequestServices.GetService(typeof(OptionsManager<AdminJWTOption>));

            var authenticationType = AuthenticationType;

            var option = options.Get(authenticationType);

            Options = option;


            base.OnActionExecuting(context);
        }


        protected AdminJWTOption Options { get; private set; }
    }

    public delegate ResultReturn CommandHandler(string cmdName);
}